package com.ttbj.product.api.impl;

import java.math.BigDecimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ttbj.core.util.CurrencyUtils;
import com.ttbj.core.util.StringUtil;
import com.ttbj.move_rule.service.MoveBillService;
import com.ttbj.product.ConvertPredict;
import com.ttbj.product.api.CostFacade;
import com.ttbj.product.api.LocationFacade;
import com.ttbj.product.api.OwnerFacade;
import com.ttbj.product.bean.dto.BillCostDto;
import com.ttbj.product.bean.dto.CargoDto;
import com.ttbj.product.bean.dto.CoordDto;
import com.ttbj.product.bean.dto.Distance;
import com.ttbj.product.bean.dto.OrderDto;
import com.ttbj.product.bean.dto.OwnerDto;
import com.ttbj.rule.dao.CarriageRuleMapper;
import com.ttbj.rule.po.CarriageRule;
import com.ttbj.rule.service.BillService;
import com.ttbj.rule.service.WtBillService;
import com.ttbj.rule.service.impl.BillServiceAlpha;
import com.ttbj.util.ArrayUtils;
import com.ttbj.util.Assert;
import com.ttbj.util.ResultUtil;
import com.ttbj.util.ViewModelUtil;

@Service("costFacade")
public class CostFacadeImpl implements CostFacade {

	private static final Logger logger = LoggerFactory.getLogger(CostFacadeImpl.class);

	@Autowired
	private LocationFacade locationFacade = null;

	@Autowired
	private OwnerFacade ownerFacade = null;

	@Autowired
	private CarriageRuleMapper carriageRuleMapper = null;

	private BillService billService = null;

	@Autowired
	private MoveBillService moveBillService = null;

	@Autowired
	private WtBillService wtBillService = null;

	@Override
	public Float getFreightCost(OrderDto orderDto) throws Exception {
		String openId = orderDto.getOpenId();
		Long orderSender = orderDto.getOrderSender();// 寄件人id
		Long orderReciver = orderDto.getOrderReciver();// 收件人id
		OwnerDto sender = ownerFacade.getOwner(openId, orderSender, 0); // 寄件人信息
		OwnerDto reciver = ownerFacade.getOwner(openId, orderReciver, 1);// 收件人信息
		CargoDto cargo = orderDto.getCargoDto();
		Assert.assertNonNullField(sender, "寄件人坐标错误,寄件人信息", 302, ArrayUtils.arrayStr("寄件人信息"), "ownerLng", "ownerLat");
		Assert.assertNonNullField(reciver, "收件人坐标错误,寄件人信息", 302, ArrayUtils.arrayStr("收件人信息"), "ownerLng", "ownerLat");
		Assert.assertNonNullField(cargo, 411, "cargoAmount", "cargoHeight");
		// 距离获取
		Distance distance = locationFacade.getDistance(new CoordDto(sender.getOwnerLng(), sender.getOwnerLat()), new CoordDto(reciver.getOwnerLng(), reciver.getOwnerLat()));
		Assert.assertFiledJsr(distance);
		// 新计费规则(final)
		CarriageRule bill = wtBillService.addWtBillRule(orderDto.getOrderTruckType());
		billService = new BillServiceAlpha(distance.getKilometer(), bill, cargo);
		Float carriage = billService.getCarriage();
		Integer orderDriverRequire = orderDto.getOrderDriverRequire();
		orderDriverRequire = null == orderDriverRequire ? 1 : orderDriverRequire;
		carriage = CurrencyUtils.toAfterTwo(carriage * orderDriverRequire);
		logger.info("运费：{}",carriage);
		return carriage;
	}

	@Override
	public Float getMoveCost(Integer billType, String senderLat, String senderLng, String reciverLat, String reciverLng, Integer floorNum, Integer pieceNum, Integer baleNum, String truckType, Integer serciveLevel, Integer orderDriverRequire) throws Exception {
		Float fee = moveBillService.getFee(3, senderLat, senderLng, reciverLat, reciverLng, floorNum, pieceNum, baleNum, truckType, serciveLevel, orderDriverRequire);
		return fee;
	}

	/**
	 * 搬家的总价费
	 * 
	 * @param billType
	 * @param senderLat
	 * @param senderLng
	 * @param reciverLat
	 * @param reciverLng
	 * @param floorNum
	 * @param pieceNum
	 * @param baleNum
	 * @param truckType
	 *            1--金杯 2--小型箱货 3--标准箱货 4--护栏敞篷 5--5.7米大型箱货 6--6.2米大型货箱
	 * @param serciveLevel
	 *            1--普通搬家 2--小件搬家 3--精品搬家 4--办公室搬家 
	 * @param orderDriverRequire
	 * @throws Exception
	 */
	public BillCostDto totalMoveCost(Integer billType, // 计费类型
			Long discountId, // 优惠券
			Integer floorNum, // 楼层
			Integer pieceNum, // 件数
			Integer baleNum, // 打包数
			String truckType, // 车辆类型
			String serciveType, // 服务类型
			Integer orderToCarry, // 是否搬运
			Integer orderToPack, // 是否打包
			Integer orderDriverRequire, // 车辆数
			Float fee, // 用户运费费用
			Float carryFee, // 用户自定义搬运费用
			Float packFee, // 用户自定义打包费用
			String senderLat, // 收件人维度
			String senderLng, // 寄件人经度
			String reciverLat, // 收件人维度
			String reciverLng// 收件人维度
	) throws Exception {
		Assert.assertNumeric(truckType, 421, "车辆类型");
		Assert.assertNumeric(serciveType, 421, "服务类型");
		Integer serciveLevel = Integer.valueOf(serciveType);//
		if (null == fee || fee < 0.01f) {
			fee = getMoveCost(billType, senderLat, senderLng, reciverLat, reciverLng, floorNum, pieceNum, baleNum, truckType, serciveLevel, null == orderDriverRequire || orderDriverRequire <= 0 ? 1 : orderDriverRequire);
		}
		// 总费用
		Float allFee = fee +  carryFee +  packFee ;
		if (null == allFee || allFee < 0.01f) {
			ResultUtil.throwExcepion(ResultUtil.createFail("message", 232), "支付额不能小于1分");
		}
		//保留小数点后二位
		allFee = CurrencyUtils.toAfterTwo(allFee);
		return new BillCostDto(allFee, fee, carryFee, packFee);
	}

	@Override
	public Float getCarryCost(Integer floorNum) {
		Float carryFee = moveBillService.carryFee(floorNum);
		return CurrencyUtils.toAfterTwo(carryFee);
	}

	@Override
	public Float getPackCost(Integer pieceNum) {
		Float packFee = moveBillService.packFee(pieceNum);
		return CurrencyUtils.toAfterTwo(packFee);
	}

 
}
